package com.xxx.video.network.responses;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;


import com.xxx.video.R;
import com.xxx.video.commen.utils.FileUtils;
import com.xxx.video.commen.utils.StringUtils;
import com.xxx.video.network.configs.NetWorkConstants;
import com.xxx.video.network.exceptions.NetWorkException;
import com.xxx.video.network.listeners.DownloadFileListener;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class DownloadFileCallback implements Callback {
    /**
     * this is a download file call back
     */
    private DownloadFileListener mDownloadFileListener;
    /**
     * msg tag
     */
    private static final int PROGRESS_MESSAGE = 0x01;
    /**
     * handler sg
     */
    private final Handler mHandler;
    /**
     * save file path
     */
    private String mFilePath;

    public DownloadFileCallback(DisposeDataHandle disposeDataHandle) {
        this.mDownloadFileListener = (DownloadFileListener) disposeDataHandle.mCommonResponseListener;
        this.mFilePath = disposeDataHandle.filePath;
        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case PROGRESS_MESSAGE:
                        if (mDownloadFileListener != null) {
                            mDownloadFileListener.onProgress((int) msg.obj);
                        }
                        break;
                    default:
                        break;
                }
            }
        };

    }

    @Override
    public void onFailure(Call call, final IOException ioException) {
        mHandler.post(() -> {
            if (mDownloadFileListener != null) {
                mDownloadFileListener.onFailure(new NetWorkException(NetWorkConstants.NetWorkErrorCode.NET_WORK_ERROR, ioException));
            }
        });

    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final File file = handlerResponse(response);
        /*
         * not write  file success
         */
        mHandler.post(() -> {
            if (file == null) {
                if (mDownloadFileListener != null) {
                    mDownloadFileListener.onFailure(new NetWorkException(NetWorkConstants.NetWorkErrorCode.IO_ERROR, StringUtils.getInstance().getString(R.string.net_work_write_file_error)));
                }
            } else {
                /*
                 * write file success
                 */
                if (mDownloadFileListener != null) {
                    mDownloadFileListener.onSuccess(file, "");
                }
            }
        });

    }

    /**
     * handler response
     *
     * @param response response
     * @return write  file
     */
    private File handlerResponse(Response response) {

        byte[] buffer = new byte[2048];

        InputStream inputStream = null;

        FileOutputStream fileOutputStream = null;

        /*
         * write length yet
         */
        long writeLength = 0;
        /*
         * total file length
         */
        final long totalLength;
        try {
            /*
             * check file path
             */
            FileUtils.getInstance().checkLocalFilePath(mFilePath);
            /*
             * get file
             */
            File file = new File(mFilePath);
            fileOutputStream = new FileOutputStream(file);
            /*
             * get input stream
             */
            inputStream = response.body().byteStream();
            /*
             * get total length
             */
            totalLength = response.body().contentLength();
            /*
             * read length
             */
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                /*
                 * write file
                 */
                fileOutputStream.write(buffer, 0, length);
                /*
                 * write length yet
                 */
                writeLength += length;
                int mProgress = (int) (writeLength / totalLength * 100);
                /*
                 * send msg with progress
                 */
                mHandler.obtainMessage(PROGRESS_MESSAGE, mProgress).sendToTarget();
            }
            fileOutputStream.flush();
            return file;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            /*
             * close stream
             */
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
